package com.rainbow.chat.test.socket;

import com.rainbow.chat.common.ChatMsg;
import com.rainbow.chat.common.ChatUtil;
import com.rainbow.chat.enums.ChatMsgType;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.SneakyThrows;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

/**
 * @Author: Usher
 * @Description:
 */
public class SocketClient {
    private static Bootstrap bootstrap;
    private static Channel channel;
    private static ChannelFutureListener channelFutureListener = null;
    private static final Integer UID = 1;
    private String host;
    private int port;

    public SocketClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void start() throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    //.remoteAddress(new InetSocketAddress(host, port))
                    .handler(new SocketClientInit())
                    .option(ChannelOption.TCP_NODELAY,true)
                    .option(ChannelOption.SO_KEEPALIVE, true)
                    .option(ChannelOption.SO_TIMEOUT, 5000)
            ;

            channelFutureListener = new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture f) {
                    if (f.isSuccess()) {
                        System.out.println("重新连接服务器成功");
                    } else {
                        System.out.println("重新连接服务器失败");
                        //  3秒后重新连接
                        f.channel().eventLoop().schedule(new Runnable() {
                            @SneakyThrows
                            @Override
                            public void run() {
                                channel = doConnect().sync().channel();
                            }
                        }, 3, TimeUnit.SECONDS);
                    }
                }
            };
            channel = doConnect().sync().channel();
            // test
            BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
            String[] lines;
            String line;
            ChatMsg chatMsg = new ChatMsg();
            while (true){
                line = input.readLine();
                try{
                    lines = line.split(",",4);
                    chatMsg.setType(ChatMsgType.fromValue(Integer.parseInt(lines[0])));
                    chatMsg.setFromUid(UID);
                    chatMsg.setGroupId(Integer.parseInt(lines[1]));
                    chatMsg.setToUid(Integer.parseInt(lines[2]));
                    chatMsg.setMsg(lines[3]);
                    channel.writeAndFlush(ChatUtil.getMsg(chatMsg));
                }catch (Exception e){
                    System.out.println("格式错误 : type,group,to,msg");
                }
            }
            // 阻塞等待 服务器关闭
            //channel.closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            group.shutdownGracefully().sync();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        new SocketClient("localhost",9999).start();
    }

    //  连接到服务端
    public ChannelFuture doConnect() {
        System.out.println("doConnect");
        ChannelFuture future = null;
        try {
            future = bootstrap.connect(new InetSocketAddress(
                    this.host, this.port));
            future.addListener(channelFutureListener);
            return future;
        } catch (Exception e) {
            e.printStackTrace();
            //future.addListener(channelFutureListener);
            System.out.println("关闭连接");
            return null;
        }
    }
}